package com.cy.aircompressor.main.home.fragment.v2;

import android.os.Build;
import android.text.TextUtils;

import androidx.fragment.app.FragmentManager;

import com.cy.aircompressor.config.AirConfig;
import com.cy.aircompressor.entity.linechart.LineChartItemEntry;
import com.cy.aircompressor.entity.linechart.LineLegend;
import com.cy.aircompressor.entity.linechart.LineNewData;
import com.cy.aircompressor.entity.select.SelectDict;
import com.cy.aircompressor.entity.sensor.Sensor;
import com.cy.aircompressor.entity.sensor.SensorAgg;
import com.cy.aircompressor.entity.sensor.SensorLatestData;
import com.cy.aircompressor.entity.sensor.SensorStatisticsData;
import com.cy.aircompressor.main.view.chart.LineChartScrollView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class LineChartHelper {
    private String[] water_oil_pressure = {"pressure_oil", "pressure_water"};
    private String[] coordinate_axis = {"x", "y", "z"};

    private static String[] line_color = {"#CF931F", "#CF1F5E", "#1F66CF"};
    public static List<String> colors = Arrays.asList(line_color);
    public FragmentManager fragmentManager;

    private static class SingletonHolder {

        private static final LineChartHelper INSTANCE = new LineChartHelper();
    }

    public static LineChartHelper get() {
        return LineChartHelper.SingletonHolder.INSTANCE;
    }

    public void setFragmentManager(FragmentManager fragmentManager) {
        this.fragmentManager = fragmentManager;
    }


    /**
     * 初始化震动曲线图基础数据
     *
     * @return
     */
    public void initLineChartScrollViewDatas(LineChartScrollView lineChartScrollView, boolean isVibration) {
        List<LineChartItemEntry> itemEntries = new ArrayList<>();
        List<SelectDict> compressorPoints = AirConfig.get().compressorPoints;
        List<SelectDict> pointCodes = getSelectDicts(compressorPoints, isVibration);
        pointCodes.forEach(new Consumer<SelectDict>() {
            @Override
            public void accept(SelectDict point) {
                String pointCode = point.getValue();
                if (!TextUtils.equals(pointCode, "pressure_water")) {
                    LineChartItemEntry itemEntry = new LineChartItemEntry();
                    itemEntry.setPointCode(pointCode);
                    itemEntry.setUnit(getUnit(pointCode));
                    itemEntry.setTitleName(getTitleName(pointCode));
                    itemEntry.setLineNewDatas(getLineNewDatas(pointCode));
                    itemEntry.setLineLegends(getLineLegends(pointCode));
                    itemEntry.setVibration(isVibration);
                    itemEntry.setSpeed(true);
                    itemEntries.add(itemEntry);
                }
            }
        });
        lineChartScrollView.initView(itemEntries);
    }


    /**
     * 同步传感器
     *
     * @param itemEntries
     * @param sensors
     */
    public void setSensorToList(List<LineChartItemEntry> itemEntries, List<Sensor> sensors) {
        if (itemEntries == null) return;
        itemEntries.forEach(new Consumer<LineChartItemEntry>() {
            @Override
            public void accept(LineChartItemEntry lineChartItemEntry) {
                if (sensors == null) {
                    lineChartItemEntry.setSensorAggs(null);
                } else {
                    List<SensorAgg> sensorAggs = filterPoints(lineChartItemEntry.getPointCode(), sensors);
                    lineChartItemEntry.setSensorAggs(sensorAggs);
                }
            }
        });
    }

    /**
     * 同步最新数据
     *
     * @param itemEntries
     * @param latestData
     */
    public void sensorLatestDataToList(List<LineChartItemEntry> itemEntries, SensorLatestData latestData) {
        itemEntries.forEach(new Consumer<LineChartItemEntry>() {
            @Override
            public void accept(LineChartItemEntry lineChartItemEntry) {
                lineChartItemEntry.setSensorLatestData(latestData);
            }
        });
    }

    /**
     * 同步统计数据
     *
     * @param itemEntries
     * @param statisticsDatas
     */
    public void sensorStatisticsDataToList(List<LineChartItemEntry> itemEntries, List<SensorStatisticsData> statisticsDatas) {
        if (itemEntries == null) return;
        if (statisticsDatas == null) return;
        if (statisticsDatas.size() == 0) return;

        itemEntries.forEach(new Consumer<LineChartItemEntry>() {
            @Override
            public void accept(LineChartItemEntry lineChartItemEntry) {
                putStatisticsDataToSensor(lineChartItemEntry, statisticsDatas);
            }
        });
    }

    private void putStatisticsDataToSensor(LineChartItemEntry lineChartItemEntry, List<SensorStatisticsData> statisticsDatas) {
        String sn = statisticsDatas.get(0).getSn();
        List<SensorAgg> sensorAggs = lineChartItemEntry.getSensorAggs();
        if (sensorAggs != null) {
            sensorAggs.forEach(new Consumer<SensorAgg>() {
                @Override
                public void accept(SensorAgg sensorAgg) {
                    if (TextUtils.equals(sensorAgg.getSensor().getSn(), sn)) {
                        sensorAgg.setSensorStatisticsData(statisticsDatas);
                    }
                }
            });
        }
    }

    /**
     * 根据空压机点位筛选传感器
     *
     * @param pointCode
     * @param sensors
     * @return
     */
    public List<SensorAgg> filterPoints(String pointCode, List<Sensor> sensors) {
        List<Sensor> results = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            results = sensors.stream()
                    .filter(new Predicate<Sensor>() {
                        @Override
                        public boolean test(Sensor sensor) {
                            boolean status;
                            boolean isPressureOil = TextUtils.equals(pointCode, "pressure_oil");
                            if (isPressureOil) {
                                status = (TextUtils.equals(sensor.getCompressorPointCode(), water_oil_pressure[0])
                                        || TextUtils.equals(sensor.getCompressorPointCode(), water_oil_pressure[1]));
                            } else {
                                status = TextUtils.equals(sensor.getCompressorPointCode(), pointCode);
                            }
                            return status;
                        }
                    }).collect(Collectors.toList());
        }
        if (results == null || results.size() == 0) return null;
        List<SensorAgg> sensorAggs = new ArrayList<>();
        for (Sensor sensor : results) {
            SensorAgg sensorAgg = new SensorAgg();
            sensorAgg.setSensor(sensor);
            sensorAggs.add(sensorAgg);
        }
        return sensorAggs;
    }


    /**
     * 获取LineNewData
     */
    private List<LineNewData> getLineNewDatas(String pointCode) {
        switch (pointCode) {
            case "vibration1":
            case "vibration2":
            case "vibration3":
                return getCoordinateAxis(pointCode);
            case "temperature":
            case "pressure":
                return getPressureTemperature(pointCode);
            case "pressure_oil":
            case "pressure_water":
                return getWaterOil(pointCode);

        }
        return null;
    }

    /**
     * 获取单位
     */
    private List<LineLegend> getLineLegends(String pointCode) {
        switch (pointCode) {
            case "vibration1":
            case "vibration2":
            case "vibration3":
                return getVibrationLegend(pointCode);
            case "temperature":
            case "pressure":
                return getTemperaturePressureLegend(pointCode);
            case "pressure_oil":
            case "pressure_water":
                return getWaterOilLegend();

        }
        return null;
    }

    private List<LineNewData> getCoordinateAxis(String pointCode) {
        List<String> coordinateAxis = Arrays.asList(coordinate_axis);
        List<LineNewData> newDataList = new ArrayList<>();
        coordinateAxis.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                LineNewData lineNewData = new LineNewData(getNewDataName(s), getUnit(pointCode), pointCode, "body");
                newDataList.add(lineNewData);
            }
        });
        return newDataList;
    }


    private List<LineNewData> getPressureTemperature(String pointCode) {
        List<SelectDict> compressorParts = AirConfig.get().compressorParts;
        List<LineNewData> newDataList = new ArrayList<>();
        compressorParts.forEach(new Consumer<SelectDict>() {
            @Override
            public void accept(SelectDict part) {
                if (!TextUtils.equals(part.getValue(), "body")) {
                    LineNewData lineNewData = new LineNewData(part.getLabel(), getUnit(pointCode), pointCode, part.getValue());
                    newDataList.add(lineNewData);
                }
            }
        });
        return newDataList;
    }

    private List<LineNewData> getWaterOil(String pointCode) {
        List<String> waterOilPoints = Arrays.asList(water_oil_pressure);
        List<LineNewData> newDataList = new ArrayList<>();
        waterOilPoints.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                LineNewData lineNewData = new LineNewData(getNewDataName(s), getUnit(pointCode), s, "body");
                newDataList.add(lineNewData);
            }
        });
        return newDataList;
    }


    private List<LineLegend> getVibrationLegend(String pointCode) {
        List<LineLegend> lineLegends = new ArrayList<>();
        for (int i = 0; i < coordinate_axis.length; i++) {
            LineLegend lineLegend = new LineLegend(getNewDataName(coordinate_axis[i]), line_color[i], pointCode, "body");
            lineLegends.add(lineLegend);
        }
        return lineLegends;
    }

    private List<LineLegend> getTemperaturePressureLegend(String pointCode) {
        List<LineLegend> lineLegends = new ArrayList<>();
        List<SelectDict> compressorParts = AirConfig.get().compressorParts;
        for (int i = 0; i < compressorParts.size(); i++) {
            SelectDict part = compressorParts.get(i);
            if (!TextUtils.equals(part.getValue(), "body")) {
                LineLegend lineLegend = new LineLegend(part.getLabel(), line_color[i], pointCode, part.getValue());
                lineLegends.add(lineLegend);
            }
        }
        return lineLegends;
    }

    private List<LineLegend> getWaterOilLegend() {
        List<LineLegend> lineLegends = new ArrayList<>();
        for (int i = 0; i < water_oil_pressure.length; i++) {
            LineLegend lineLegend = new LineLegend(getNewDataName(water_oil_pressure[i]), line_color[i], water_oil_pressure[i], "body");
            lineLegends.add(lineLegend);
        }
        return lineLegends;
    }


    /**
     * 获取标题名字
     */
    private String getTitleName(String pointCode) {
        switch (pointCode) {
            case "vibration1":
                return "机身震动变化趋势";
            case "vibration2":
                return "一级气缸震动变化趋势";
            case "vibration3":
                return "二三级气缸震动变化趋势";
            case "temperature":
                return "温度变化趋势";
            case "pressure":
                return "压力变化趋势";
            case "pressure_water":
            case "pressure_oil":
                return "油压,水压变化趋势";

        }
        return null;
    }


    /**
     * 获取单位
     */
    private String getUnit(String pointCode) {
        if (pointCode.contains("vibration")) {
            return "mm/s";
        } else if (pointCode.contains("temperature")) {
            return "℃";
        } else if (pointCode.contains("pressure")) {
            return "Mpa";
        }
        return null;
    }


    private String getNewDataName(String tag) {
        switch (tag) {
            case "cylinder_1st":
                return "一级气缸";
            case "cylinder_2nd":
                return "二级气缸";
            case "cylinder_3rd":
                return "三级气缸";
            case "pressure_oil":
                return "油压";
            case "pressure_water":
                return "水压";
            case "x":
                return "x轴";
            case "y":
                return "y轴";
            case "z":
                return "z轴";
            default:
                return "";
        }
    }

    private List<SelectDict> getSelectDicts(List<SelectDict> selectDicts, boolean isVibration) {
        if (selectDicts == null) return null;
        List<SelectDict> dictList = selectDicts.stream().filter(new Predicate<SelectDict>() {
            @Override
            public boolean test(SelectDict selectDict) {
                if (isVibration) {
                    return selectDict.getValue().contains("vibration");
                } else {
                    return !selectDict.getValue().contains("vibration");
                }
            }
        }).collect(Collectors.toList());
        return dictList;
    }

    private List<SelectDict> getUnselectDicts(List<SelectDict> selectDicts, String value) {
        if (selectDicts == null) return null;
        List<SelectDict> dictList = selectDicts.stream().filter(new Predicate<SelectDict>() {
            @Override
            public boolean test(SelectDict selectDict) {
                return !selectDict.getValue().contains(value);
            }
        }).collect(Collectors.toList());
        return dictList;
    }


    public String getColor(String code) {
        switch (code) {
            case "cylinder_1st":
                return colors.get(0);
            case "cylinder_2nd":
                return colors.get(1);
            case "cylinder_3rd":
                return colors.get(2);
            case "pressure_oil":
                return colors.get(0);
            case "pressure_water":
                return colors.get(1);
            case "x":
                return colors.get(0);
            case "y":
                return colors.get(1);
            case "z":
                return colors.get(2);
            default:
                return "#FFFFFF";
        }
    }
}
